require(igraph)
g <- make_graph("Zachary")
plot(g)
R Sienna Tutorial
Data
getwd()
load("twitter_20190919.RData") #change to your working directory
str(twitter_20190919, 1)
keyf <- twitter_20190919[[1]]
#keyf is dataframe on 147 Dutch MPs
mydata <- twitter_20190919[[2]]
# mydata is object ready to analyze in RSiena. Nodes are the same as in keyf and seats. Contains twitter data at three timepounts. Three layers: fnet (who follows whom), atmnet (who amentions whom) and rnter (who retweets whom). Also contains timevariant information on nodes.
seats <- twitter_20190919[[3]]
#seats is dataset which contains coordinates of seats in House of Parliament in Netherlands
Densities
# retrieve nominationdata from rsiena object
fnet <- mydata$depvars$fnet
atmnet <- mydata$depvars$atmnet
rtnet <- mydata$depvars$rtnet
# retrieve node-attributes from rsiena object
vrouw <- mydata$cCovars$vrouw
partij <- mydata$cCovars$partij
ethminz <- mydata$cCovars$ethminz
lft <- mydata$cCovars$lft
# de-mean-center node attributes
ethminz <- ethminz + attributes(ethminz)$mean
partij <- partij + attributes(partij)$mean
vrouw <- vrouw + attributes(vrouw)$mean
lft <- lft + attributes(lft)$mean
# construct matrices for similarity for each dimension (dyad characteristics)
vrouwm <- fhomomat(vrouw)
partijm <- fhomomat(partij)
ethminzm <- fhomomat(ethminz)
# just for fun, make dyad characteristic indicating whether both nodes are ethnic minorities
xmat <- matrix(ethminz, nrow = length(ethminz), ncol = length(ethminz))
xmatt <- t(xmat)
minoritym <- xmat == 1 & xmatt == 1
# for age max 5 year difference / for descriptives
xmat <- matrix(lft, nrow = length(lft), ncol = length(lft))
xmatt <- t(xmat)
lftm <- (abs(xmat - xmatt) < 6)
# calculate all possible similar dyads, not the focus of this exercise. fndyads2(fnet[,,1], vrouwm)
# fndyads2(fnet[,,3], vrouwm) fndyads2(fnet[,,1], partijm) fndyads2(fnet[,,3], partijm)
# fndyads2(fnet[,,1], ethminzm) fndyads2(fnet[,,3], ethminzm)
# make a big object to store all results
desmat <- matrix(NA, nrow = 10, ncol = 9)
# lets start using our functions
desmat[1, 1] <- fdensity(fnet[, , 1])
desmat[1, 2] <- fdensity(fnet[, , 2])
desmat[1, 3] <- fdensity(fnet[, , 3])
desmat[2, 1] <- fdensityintra(fnet[, , 1], vrouwm)
desmat[2, 2] <- fdensityintra(fnet[, , 2], vrouwm)
desmat[2, 3] <- fdensityintra(fnet[, , 3], vrouwm)
desmat[3, 1] <- fdensityinter(fnet[, , 1], vrouwm)
desmat[3, 2] <- fdensityinter(fnet[, , 2], vrouwm)
desmat[3, 3] <- fdensityinter(fnet[, , 3], vrouwm)
desmat[4, 1] <- fdensityintra(fnet[, , 1], partijm)
desmat[4, 2] <- fdensityintra(fnet[, , 2], partijm)
desmat[4, 3] <- fdensityintra(fnet[, , 3], partijm)
desmat[5, 1] <- fdensityinter(fnet[, , 1], partijm)
desmat[5, 2] <- fdensityinter(fnet[, , 2], partijm)
desmat[5, 3] <- fdensityinter(fnet[, , 3], partijm)
desmat[6, 1] <- fdensityintra(fnet[, , 1], ethminzm)
desmat[6, 2] <- fdensityintra(fnet[, , 2], ethminzm)
desmat[6, 3] <- fdensityintra(fnet[, , 3], ethminzm)
desmat[7, 1] <- fdensityinter(fnet[, , 1], ethminzm)
desmat[7, 2] <- fdensityinter(fnet[, , 2], ethminzm)
desmat[7, 3] <- fdensityinter(fnet[, , 3], ethminzm)
desmat[8, 1] <- fdensityinter(fnet[, , 1], minoritym)
desmat[8, 2] <- fdensityinter(fnet[, , 2], minoritym)
desmat[8, 3] <- fdensityinter(fnet[, , 3], minoritym)
desmat[9, 1] <- fdensityintra(fnet[, , 1], lftm)
desmat[9, 2] <- fdensityintra(fnet[, , 2], lftm)
desmat[9, 3] <- fdensityintra(fnet[, , 3], lftm)
desmat[10, 1] <- fdensityinter(fnet[, , 1], lftm)
desmat[10, 2] <- fdensityinter(fnet[, , 2], lftm)
desmat[10, 3] <- fdensityinter(fnet[, , 3], lftm)
desmat[1, 1 + 3] <- fdensity(atmnet[, , 1])
desmat[1, 2 + 3] <- fdensity(atmnet[, , 2])
desmat[1, 3 + 3] <- fdensity(atmnet[, , 3])
desmat[2, 1 + 3] <- fdensityintra(atmnet[, , 1], vrouwm)
desmat[2, 2 + 3] <- fdensityintra(atmnet[, , 2], vrouwm)
desmat[2, 3 + 3] <- fdensityintra(atmnet[, , 3], vrouwm)
desmat[3, 1 + 3] <- fdensityinter(atmnet[, , 1], vrouwm)
desmat[3, 2 + 3] <- fdensityinter(atmnet[, , 2], vrouwm)
desmat[3, 3 + 3] <- fdensityinter(atmnet[, , 3], vrouwm)
desmat[4, 1 + 3] <- fdensityintra(atmnet[, , 1], partijm)
desmat[4, 2 + 3] <- fdensityintra(atmnet[, , 2], partijm)
desmat[4, 3 + 3] <- fdensityintra(atmnet[, , 3], partijm)
desmat[5, 1 + 3] <- fdensityinter(atmnet[, , 1], partijm)
desmat[5, 2 + 3] <- fdensityinter(atmnet[, , 2], partijm)
desmat[5, 3 + 3] <- fdensityinter(atmnet[, , 3], partijm)
desmat[6, 1 + 3] <- fdensityintra(atmnet[, , 1], ethminzm)
desmat[6, 2 + 3] <- fdensityintra(atmnet[, , 2], ethminzm)
desmat[6, 3 + 3] <- fdensityintra(atmnet[, , 3], ethminzm)
desmat[7, 1 + 3] <- fdensityinter(atmnet[, , 1], ethminzm)
desmat[7, 2 + 3] <- fdensityinter(atmnet[, , 2], ethminzm)
desmat[7, 3 + 3] <- fdensityinter(atmnet[, , 3], ethminzm)
desmat[8, 1 + 3] <- fdensityinter(atmnet[, , 1], minoritym)
desmat[8, 2 + 3] <- fdensityinter(atmnet[, , 2], minoritym)
desmat[8, 3 + 3] <- fdensityinter(atmnet[, , 3], minoritym)
desmat[9, 1 + 3] <- fdensityintra(atmnet[, , 1], lftm)
desmat[9, 2 + 3] <- fdensityintra(atmnet[, , 2], lftm)
desmat[9, 3 + 3] <- fdensityintra(atmnet[, , 3], lftm)
desmat[10, 1 + 3] <- fdensityinter(atmnet[, , 1], lftm)
desmat[10, 2 + 3] <- fdensityinter(atmnet[, , 2], lftm)
desmat[10, 3 + 3] <- fdensityinter(atmnet[, , 3], lftm)
desmat[1, 1 + 6] <- fdensity(rtnet[, , 1])
desmat[1, 2 + 6] <- fdensity(rtnet[, , 2])
desmat[1, 3 + 6] <- fdensity(rtnet[, , 3])
desmat[2, 1 + 6] <- fdensityintra(rtnet[, , 1], vrouwm)
desmat[2, 2 + 6] <- fdensityintra(rtnet[, , 2], vrouwm)
desmat[2, 3 + 6] <- fdensityintra(rtnet[, , 3], vrouwm)
desmat[3, 1 + 6] <- fdensityinter(rtnet[, , 1], vrouwm)
desmat[3, 2 + 6] <- fdensityinter(rtnet[, , 2], vrouwm)
desmat[3, 3 + 6] <- fdensityinter(rtnet[, , 3], vrouwm)
desmat[4, 1 + 6] <- fdensityintra(rtnet[, , 1], partijm)
desmat[4, 2 + 6] <- fdensityintra(rtnet[, , 2], partijm)
desmat[4, 3 + 6] <- fdensityintra(rtnet[, , 3], partijm)
desmat[5, 1 + 6] <- fdensityinter(rtnet[, , 1], partijm)
desmat[5, 2 + 6] <- fdensityinter(rtnet[, , 2], partijm)
desmat[5, 3 + 6] <- fdensityinter(rtnet[, , 3], partijm)
desmat[6, 1 + 6] <- fdensityintra(rtnet[, , 1], ethminzm)
desmat[6, 2 + 6] <- fdensityintra(rtnet[, , 2], ethminzm)
desmat[6, 3 + 6] <- fdensityintra(rtnet[, , 3], ethminzm)
desmat[7, 1 + 6] <- fdensityinter(rtnet[, , 1], ethminzm)
desmat[7, 2 + 6] <- fdensityinter(rtnet[, , 2], ethminzm)
desmat[7, 3 + 6] <- fdensityinter(rtnet[, , 3], ethminzm)
desmat[8, 1 + 6] <- fdensityinter(rtnet[, , 1], minoritym)
desmat[8, 2 + 6] <- fdensityinter(rtnet[, , 2], minoritym)
desmat[8, 3 + 6] <- fdensityinter(rtnet[, , 3], minoritym)
desmat[9, 1 + 6] <- fdensityintra(rtnet[, , 1], lftm)
desmat[9, 2 + 6] <- fdensityintra(rtnet[, , 2], lftm)
desmat[9, 3 + 6] <- fdensityintra(rtnet[, , 3], lftm)
desmat[10, 1 + 6] <- fdensityinter(rtnet[, , 1], lftm)
desmat[10, 2 + 6] <- fdensityinter(rtnet[, , 2], lftm)
desmat[10, 3 + 6] <- fdensityinter(rtnet[, , 3], lftm)
colnames(desmat) <- c("friends w1", "friends w2", "friends w3", "atmentions w1", "atmentions w2", "atmentions w3",
"retweets w1", "retweets w2", "retweets w3")
rownames(desmat) <- c("total", "same sex", "different sex", "same party", "different party", "same ethnicity",
"different ethnicity", "both minority", "same age (<6)", "different age (>5)")
desmat
# we observe a lot of homophily. Mainly big difference in density between and whithin political parties. Homophily is not that strong across social dimensions.
coleman homophily
# Because size of different subgroups vary and number of out-degrees differs between MPs, whitin party densities might be higher when MPs randomly select partner/alter. Segregation will partly be structully induced by differences in relative groups sizes and activity on twitter. Coleman's homophily index: takes relative group sizes and differences into account. 0 -> observed number of within-group ties is the same as would be expected under random choice. 1 -> maximum segregation. -1 -> MPs maximally avoid within group relations.
colmat <- matrix(NA, nrow = 3, ncol = 9)
colmat[1, 1] <- fscolnet(fnet[, , 1], partij)
colmat[1, 2] <- fscolnet(fnet[, , 2], partij)
colmat[1, 3] <- fscolnet(fnet[, , 3], partij)
colmat[1, 4] <- fscolnet(atmnet[, , 1], partij)
colmat[1, 5] <- fscolnet(atmnet[, , 2], partij)
colmat[1, 6] <- fscolnet(atmnet[, , 3], partij)
colmat[1, 7] <- fscolnet(rtnet[, , 1], partij)
colmat[1, 8] <- fscolnet(rtnet[, , 2], partij)
colmat[1, 9] <- fscolnet(rtnet[, , 3], partij)
colmat[2, 1] <- fscolnet(fnet[, , 1], vrouw)
colmat[2, 2] <- fscolnet(fnet[, , 2], vrouw)
colmat[2, 3] <- fscolnet(fnet[, , 3], vrouw)
colmat[2, 4] <- fscolnet(atmnet[, , 1], vrouw)
colmat[2, 5] <- fscolnet(atmnet[, , 2], vrouw)
colmat[2, 6] <- fscolnet(atmnet[, , 3], vrouw)
colmat[2, 7] <- fscolnet(rtnet[, , 1], vrouw)
colmat[2, 8] <- fscolnet(rtnet[, , 2], vrouw)
colmat[2, 9] <- fscolnet(rtnet[, , 3], vrouw)
colmat[3, 1] <- fscolnet(fnet[, , 1], ethminz)
colmat[3, 2] <- fscolnet(fnet[, , 2], ethminz)
colmat[3, 3] <- fscolnet(fnet[, , 3], ethminz)
colmat[3, 4] <- fscolnet(atmnet[, , 1], ethminz)
colmat[3, 5] <- fscolnet(atmnet[, , 2], ethminz)
colmat[3, 6] <- fscolnet(atmnet[, , 3], ethminz)
colmat[3, 7] <- fscolnet(rtnet[, , 1], ethminz)
colmat[3, 8] <- fscolnet(rtnet[, , 2], ethminz)
colmat[3, 9] <- fscolnet(rtnet[, , 3], ethminz)
colnames(colmat) <- c("friends w1", "friends w2", "friends w3", "atmentions w1", "atmentions w2", "atmentions w3",
"retweets w1", "retweets w2", "retweets w3")
rownames(colmat) <- c("party", "sex", "ethnicity")
colmat
RSienna
# defining myeff object
library(RSiena)
myeff <- getEffects(mydata)
myeff
myeff_m1 <- myeff
myeff_m1 <- includeEffects(myeff_m1, sameX, interaction1 = "partij", name = "rtnet")
# I used a seed so you will probably see the same results
myalgorithm <- sienaAlgorithmCreate(projname = "test", seed = 345654)
# to speed things up a bit, I am using more cores.
ansM1 <- siena07(myalgorithm, data = mydata, effects = myeff_m1, useCluster = TRUE, nbrNodes = 4, initC = TRUE,
batch = TRUE)
ansM1b <- siena07(myalgorithm, data = mydata, prevAns = ansM1, effects = myeff_m1, useCluster = TRUE,
nbrNodes = 4, initC = TRUE, batch = TRUE)
ansM1c <- siena07(myalgorithm, data = mydata, prevAns = ansM1b, effects = myeff_m1, useCluster = TRUE,
nbrNodes = 4, initC = TRUE, batch = TRUE)
save(ansM1, file = "ansM1a.RData")
save(ansM1b, file = "ansM1b.RData")
save(ansM1c, file = "ansM1c.RData")
load("ansM1a.RData")
load("ansM1b.RData")
load("ansM1c.RData")
ansM1
ansM1b
ansM1c
#To what extent do we observe segregation along party affiliation in the retweet network among Dutch MPs?
# Answer: the eval same partij is 1.8551. This means that we observe strong segregation along pary affiliation: people are more likely to have ties with people from the same party
RQ 1
myeff_m2 <- myeff
myeff_m2 <- includeEffects(myeff_m2, sameX, interaction1 = "partij", name = "rtnet")
myeff_m2 <- myeff
myeff_m2 <- includeEffects(myeff_m2, sameX, interaction1 = "vrouw", name = "rtnet")
myeff_m2 <- myeff
myeff_m2 <- includeEffects(myeff_m2, sameX, interaction1 = "lft", name = "rtnet")
myeff_m2 <- myeff
myeff_m2 <- includeEffects(myeff_m2, X, interaction1 = "afstand", name = "rtnet")
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQoNCg0KYGBge3J9DQpyZXF1aXJlKGlncmFwaCkNCmcgPC0gbWFrZV9ncmFwaCgiWmFjaGFyeSIpDQpwbG90KGcpDQoNCmBgYA0KDQpgYGB7cn0NCg0KYGBgDQoNCg0KYGBge3J9DQoNCmBgYA0KDQoNCg0KDQpSIFNpZW5uYSBUdXRvcmlhbCANCg0KYGBge3J9DQojIGNsZWFudXAgd29ya3NwYWNlDQpybShsaXN0ID0gbHMoKSkNCg0KIyBpbnN0YWxsIHBhY2thZ2VzDQpsaWJyYXJ5KFJTaWVuYSkNCmxpYnJhcnkoc2VsZW5pZGVyKQ0KbGlicmFyeShydmVzdCkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShuZXRzdGF0KQ0KbGlicmFyeShwaW5ncikNCmxpYnJhcnkoanNvbmxpdGUpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KG9wZW5hbGV4UikNCg0KIyBkZW5zaXR5OiBvYnNlcnZlZCByZWxhdGlvbnMgZGl2aWRlZCBieSBwb3NzaWJsZSByZWxhdGlvbnMNCmZkZW5zaXR5IDwtIGZ1bmN0aW9uKHgpIHsNCiAgICAjIHggaXMgeW91ciBub21pbmF0aW9uIG5ldHdvcmsgbWFrZSBzdXJlIGRpYWdvbmFsIGNlbGxzIGFyZSBOQQ0KICAgIGRpYWcoeCkgPC0gTkENCiAgICAjIHRha2UgY2FyZSBvZiBSU2llbmEgc3RydWN0dXJhbCB6ZXJvcywgc2V0IGFzIG1pc3NpbmcuDQogICAgeFt4ID09IDEwXSA8LSBOQQ0KICAgIHN1bSh4ID09IDEsIG5hLnJtID0gVCkvKHN1bSh4ID09IDEgfCB4ID09IDAsIG5hLnJtID0gVCkpDQp9DQoNCiMgY2FsY3VsYXRlIGludHJhZ3JvdXAgZGVuc2l0eQ0KZmRlbnNpdHlpbnRyYSA8LSBmdW5jdGlvbih4LCBBKSB7DQogICAgIyBBIGlzIG1hdHJpeCBpbmRpY2F0aW5nIHdoZXRoZXIgbm9kZXMgaW4gZHlhZCBoYXZlIHNhbWUgbm9kZSBhdHRyaWJ1dGVzDQogICAgZGlhZyh4KSA8LSBOQQ0KICAgIHhbeCA9PSAxMF0gPC0gTkENCiAgICBkaWFnKEEpIDwtIE5BDQogICAgc3VtKHggPT0gMSAmIEEgPT0gMSwgbmEucm0gPSBUKS8oc3VtKCh4ID09IDEgfCB4ID09IDApICYgQSA9PSAxLCBuYS5ybSA9IFQpKQ0KfQ0KDQojIGNhbGN1bGF0ZSBpbnRyYWdyb3VwIGRlbnNpdHkNCmZkZW5zaXR5aW50ZXIgPC0gZnVuY3Rpb24oeCwgQSkgew0KICAgICMgQSBpcyBtYXRyaXggaW5kaWNhdGluZyB3aGV0aGVyIG5vZGVzIGluIGR5YWQgaGF2ZSBzYW1lIG5vZGUgYXR0cmlidXRlcw0KICAgIGRpYWcoeCkgPC0gTkENCiAgICB4W3ggPT0gMTBdIDwtIE5BDQogICAgZGlhZyhBKSA8LSBOQQ0KICAgIHN1bSh4ID09IDEgJiBBICE9IDEsIG5hLnJtID0gVCkvKHN1bSgoeCA9PSAxIHwgeCA9PSAwKSAmIEEgIT0gMSwgbmEucm0gPSBUKSkNCn0NCg0KIyBjb25zdHJ1Y3QgZHlhZGNoYXJhY3RlcmlzdGljIHdoZXRoZXIgbm9kZXMgYXJlIHNpbWlsYXIvaG9tb2dlbm91cw0KZmhvbW9tYXQgPC0gZnVuY3Rpb24oeCkgew0KICAgICMgeCBpcyBhIHZlY3RvciBvZiBub2RlLWNvdmFyaWF0ZQ0KICAgIHhtYXQgPC0gbWF0cml4KHgsIG5yb3cgPSBsZW5ndGgoeCksIG5jb2wgPSBsZW5ndGgoeCkpDQogICAgeG1hdHQgPC0gdCh4bWF0KQ0KICAgIHhob21vIDwtIHhtYXQgPT0geG1hdHQNCiAgICByZXR1cm4oeGhvbW8pDQp9DQoNCiMgYSBmdW5jdGlvbiB0byBjYWxjdWxhdGUgYWxsIHZhbGlkIGR5YWRzLg0KZm5keWFkcyA8LSBmdW5jdGlvbih4KSB7DQogICAgZGlhZyh4KSA8LSBOQQ0KICAgIHhbeCA9PSAxMF0gPC0gTkENCiAgICAoc3VtKCh4ID09IDEgfCB4ID09IDApLCBuYS5ybSA9IFQpKQ0KfQ0KDQojIGEgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGFsbCB2YWxpZCBpbnRyYWdyb3VwZHlhZHMuDQpmbmR5YWRzMiA8LSBmdW5jdGlvbih4LCBBKSB7DQogICAgZGlhZyh4KSA8LSBOQQ0KICAgIHhbeCA9PSAxMF0gPC0gTkENCiAgICBkaWFnKEEpIDwtIE5BDQogICAgKHN1bSgoeCA9PSAxIHwgeCA9PSAwKSAmIEEgPT0gMSwgbmEucm0gPSBUKSkNCn0NCg0KDQpmc2NvbG5ldCA8LSBmdW5jdGlvbihuZXR3b3JrLCBjY292YXIpIHsNCiAgICAjIENhbGN1bGF0ZSBjb2xlbWFuIG9uIG5ldHdvcmsgbGV2ZWw6DQogICAgIyBodHRwczovL3JlYWRlci5lbHNldmllci5jb20vcmVhZGVyL3NkL3BpaS9TMDM3ODg3MzMxNDAwMDIzOT90b2tlbj1BNDJGOTlGRjZFMkI3NTA0MzZERDJDQjBEQjdCMUY0MUJERUMxNjA1MkE0NTY4M0MwMjY0NERBRjg4MjE1QTMzNzk2MzZCMkFBMTk3QjY1OTQxRDYzNzNFOUUyRUU0MTMNCiAgICANCiAgICBmaG9tb21hdCA8LSBmdW5jdGlvbih4KSB7DQogICAgICAgIHhtYXQgPC0gbWF0cml4KHgsIG5yb3cgPSBsZW5ndGgoeCksIG5jb2wgPSBsZW5ndGgoeCkpDQogICAgICAgIHhtYXR0IDwtIHQoeG1hdCkNCiAgICAgICAgeGhvbW8gPC0geG1hdCA9PSB4bWF0dA0KICAgICAgICByZXR1cm4oeGhvbW8pDQogICAgfQ0KICAgIA0KICAgIGZzdW1pbnRyYSA8LSBmdW5jdGlvbih4LCBBKSB7DQogICAgICAgICMgQSBpcyBtYXRyaXggaW5kaWNhdGluZyB3aGV0aGVyIG5vZGVzIGNvbnN0aXR1dGluZyBkeWFkIGhhdmUgc2FtZSBjaGFyYWN0ZXJpc3RpY3MNCiAgICAgICAgZGlhZyh4KSA8LSBOQQ0KICAgICAgICB4W3ggPT0gMTBdIDwtIE5BDQogICAgICAgIGRpYWcoQSkgPC0gTkENCiAgICAgICAgc3VtKHggPT0gMSAmIEEgPT0gMSwgbmEucm0gPSBUKQ0KICAgIH0NCiAgICANCiAgICAjIGV4cGVjYXRpb24gdyo9c3VtX2cgc3VtX2kgKG5pKChuZy0xKS8oTi0xKSkpDQogICAgbmV0d29ya1tuZXR3b3JrID09IDEwXSA8LSBOQQ0KICAgIG5pIDwtIHJvd1N1bXMobmV0d29yaywgbmEucm0gPSBUKQ0KICAgIG5nIDwtIE5BDQogICAgZm9yIChpIGluIDE6bGVuZ3RoKGNjb3ZhcikpIHsNCiAgICAgICAgbmdbaV0gPC0gdGFibGUoY2NvdmFyKVtyb3duYW1lcyh0YWJsZShjY292YXIpKSA9PSBjY292YXJbaV1dDQogICAgfQ0KICAgIE4gPC0gbGVuZ3RoKGNjb3ZhcikNCiAgICB3ZXhwIDwtIHN1bShuaSAqICgobmcgLSAxKS8oTiAtIDEpKSwgbmEucm0gPSBUKQ0KICAgIA0KICAgICMgd2dnMSBob3cgbWFueSBpbnRyYWdyb3VwIHRpZXMNCiAgICB3IDwtIGZzdW1pbnRyYShuZXR3b3JrLCBmaG9tb21hdChjY292YXIpKQ0KICAgIA0KICAgIFNjb2xfbmV0IDwtIGlmZWxzZSh3ID49IHdleHAsICh3IC0gd2V4cCkvKHN1bShuaSwgbmEucm0gPSBUKSAtIHdleHApLCAodyAtIHdleHApL3dleHApDQogICAgcmV0dXJuKFNjb2xfbmV0KQ0KfQ0KDQpgYGANCg0KDQpEYXRhDQpgYGB7cn0NCmdldHdkKCkNCg0KbG9hZCgidHdpdHRlcl8yMDE5MDkxOS5SRGF0YSIpICAjY2hhbmdlIHRvIHlvdXIgd29ya2luZyBkaXJlY3RvcnkNCnN0cih0d2l0dGVyXzIwMTkwOTE5LCAxKQ0KDQprZXlmIDwtIHR3aXR0ZXJfMjAxOTA5MTlbWzFdXQ0KI2tleWYgaXMgZGF0YWZyYW1lIG9uIDE0NyBEdXRjaCBNUHMNCm15ZGF0YSA8LSB0d2l0dGVyXzIwMTkwOTE5W1syXV0NCiMgbXlkYXRhIGlzIG9iamVjdCByZWFkeSB0byBhbmFseXplIGluIFJTaWVuYS4gTm9kZXMgYXJlIHRoZSBzYW1lIGFzIGluIGtleWYgYW5kIHNlYXRzLiBDb250YWlucyB0d2l0dGVyIGRhdGEgYXQgdGhyZWUgdGltZXBvdW50cy4gVGhyZWUgbGF5ZXJzOiBmbmV0ICh3aG8gZm9sbG93cyB3aG9tKSwgYXRtbmV0ICh3aG8gYW1lbnRpb25zIHdob20pIGFuZCBybnRlciAod2hvIHJldHdlZXRzIHdob20pLiBBbHNvIGNvbnRhaW5zIHRpbWV2YXJpYW50IGluZm9ybWF0aW9uIG9uIG5vZGVzLg0Kc2VhdHMgPC0gdHdpdHRlcl8yMDE5MDkxOVtbM11dDQojc2VhdHMgaXMgZGF0YXNldCB3aGljaCBjb250YWlucyBjb29yZGluYXRlcyBvZiBzZWF0cyBpbiBIb3VzZSBvZiBQYXJsaWFtZW50IGluIE5ldGhlcmxhbmRzDQoNCg0KDQoNCmBgYA0KDQoNCkRlbnNpdGllcw0KYGBge3J9DQojIHJldHJpZXZlIG5vbWluYXRpb25kYXRhIGZyb20gcnNpZW5hIG9iamVjdA0KZm5ldCA8LSBteWRhdGEkZGVwdmFycyRmbmV0DQphdG1uZXQgPC0gbXlkYXRhJGRlcHZhcnMkYXRtbmV0DQpydG5ldCA8LSBteWRhdGEkZGVwdmFycyRydG5ldA0KDQojIHJldHJpZXZlIG5vZGUtYXR0cmlidXRlcyBmcm9tIHJzaWVuYSBvYmplY3QNCnZyb3V3IDwtIG15ZGF0YSRjQ292YXJzJHZyb3V3DQpwYXJ0aWogPC0gbXlkYXRhJGNDb3ZhcnMkcGFydGlqDQpldGhtaW56IDwtIG15ZGF0YSRjQ292YXJzJGV0aG1pbnoNCmxmdCA8LSBteWRhdGEkY0NvdmFycyRsZnQNCg0KIyBkZS1tZWFuLWNlbnRlciBub2RlIGF0dHJpYnV0ZXMNCmV0aG1pbnogPC0gZXRobWlueiArIGF0dHJpYnV0ZXMoZXRobWlueikkbWVhbg0KcGFydGlqIDwtIHBhcnRpaiArIGF0dHJpYnV0ZXMocGFydGlqKSRtZWFuDQp2cm91dyA8LSB2cm91dyArIGF0dHJpYnV0ZXModnJvdXcpJG1lYW4NCmxmdCA8LSBsZnQgKyBhdHRyaWJ1dGVzKGxmdCkkbWVhbg0KDQojIGNvbnN0cnVjdCBtYXRyaWNlcyBmb3Igc2ltaWxhcml0eSBmb3IgZWFjaCBkaW1lbnNpb24gKGR5YWQgY2hhcmFjdGVyaXN0aWNzKQ0KdnJvdXdtIDwtIGZob21vbWF0KHZyb3V3KQ0KcGFydGlqbSA8LSBmaG9tb21hdChwYXJ0aWopDQpldGhtaW56bSA8LSBmaG9tb21hdChldGhtaW56KQ0KDQojIGp1c3QgZm9yIGZ1biwgbWFrZSBkeWFkIGNoYXJhY3RlcmlzdGljIGluZGljYXRpbmcgd2hldGhlciBib3RoIG5vZGVzIGFyZSBldGhuaWMgbWlub3JpdGllcw0KeG1hdCA8LSBtYXRyaXgoZXRobWlueiwgbnJvdyA9IGxlbmd0aChldGhtaW56KSwgbmNvbCA9IGxlbmd0aChldGhtaW56KSkNCnhtYXR0IDwtIHQoeG1hdCkNCm1pbm9yaXR5bSA8LSB4bWF0ID09IDEgJiB4bWF0dCA9PSAxDQoNCiMgZm9yIGFnZSBtYXggNSB5ZWFyIGRpZmZlcmVuY2UgLyBmb3IgZGVzY3JpcHRpdmVzDQp4bWF0IDwtIG1hdHJpeChsZnQsIG5yb3cgPSBsZW5ndGgobGZ0KSwgbmNvbCA9IGxlbmd0aChsZnQpKQ0KeG1hdHQgPC0gdCh4bWF0KQ0KbGZ0bSA8LSAoYWJzKHhtYXQgLSB4bWF0dCkgPCA2KQ0KDQojIGNhbGN1bGF0ZSBhbGwgcG9zc2libGUgc2ltaWxhciBkeWFkcywgbm90IHRoZSBmb2N1cyBvZiB0aGlzIGV4ZXJjaXNlLiAgZm5keWFkczIoZm5ldFssLDFdLCB2cm91d20pDQojIGZuZHlhZHMyKGZuZXRbLCwzXSwgdnJvdXdtKSBmbmR5YWRzMihmbmV0WywsMV0sIHBhcnRpam0pIGZuZHlhZHMyKGZuZXRbLCwzXSwgcGFydGlqbSkNCiMgZm5keWFkczIoZm5ldFssLDFdLCBldGhtaW56bSkgZm5keWFkczIoZm5ldFssLDNdLCBldGhtaW56bSkNCg0KIyBtYWtlIGEgYmlnIG9iamVjdCB0byBzdG9yZSBhbGwgcmVzdWx0cw0KZGVzbWF0IDwtIG1hdHJpeChOQSwgbnJvdyA9IDEwLCBuY29sID0gOSkNCg0KIyBsZXRzIHN0YXJ0IHVzaW5nIG91ciBmdW5jdGlvbnMNCmRlc21hdFsxLCAxXSA8LSBmZGVuc2l0eShmbmV0WywgLCAxXSkNCmRlc21hdFsxLCAyXSA8LSBmZGVuc2l0eShmbmV0WywgLCAyXSkNCmRlc21hdFsxLCAzXSA8LSBmZGVuc2l0eShmbmV0WywgLCAzXSkNCmRlc21hdFsyLCAxXSA8LSBmZGVuc2l0eWludHJhKGZuZXRbLCAsIDFdLCB2cm91d20pDQpkZXNtYXRbMiwgMl0gPC0gZmRlbnNpdHlpbnRyYShmbmV0WywgLCAyXSwgdnJvdXdtKQ0KZGVzbWF0WzIsIDNdIDwtIGZkZW5zaXR5aW50cmEoZm5ldFssICwgM10sIHZyb3V3bSkNCmRlc21hdFszLCAxXSA8LSBmZGVuc2l0eWludGVyKGZuZXRbLCAsIDFdLCB2cm91d20pDQpkZXNtYXRbMywgMl0gPC0gZmRlbnNpdHlpbnRlcihmbmV0WywgLCAyXSwgdnJvdXdtKQ0KZGVzbWF0WzMsIDNdIDwtIGZkZW5zaXR5aW50ZXIoZm5ldFssICwgM10sIHZyb3V3bSkNCmRlc21hdFs0LCAxXSA8LSBmZGVuc2l0eWludHJhKGZuZXRbLCAsIDFdLCBwYXJ0aWptKQ0KZGVzbWF0WzQsIDJdIDwtIGZkZW5zaXR5aW50cmEoZm5ldFssICwgMl0sIHBhcnRpam0pDQpkZXNtYXRbNCwgM10gPC0gZmRlbnNpdHlpbnRyYShmbmV0WywgLCAzXSwgcGFydGlqbSkNCmRlc21hdFs1LCAxXSA8LSBmZGVuc2l0eWludGVyKGZuZXRbLCAsIDFdLCBwYXJ0aWptKQ0KZGVzbWF0WzUsIDJdIDwtIGZkZW5zaXR5aW50ZXIoZm5ldFssICwgMl0sIHBhcnRpam0pDQpkZXNtYXRbNSwgM10gPC0gZmRlbnNpdHlpbnRlcihmbmV0WywgLCAzXSwgcGFydGlqbSkNCmRlc21hdFs2LCAxXSA8LSBmZGVuc2l0eWludHJhKGZuZXRbLCAsIDFdLCBldGhtaW56bSkNCmRlc21hdFs2LCAyXSA8LSBmZGVuc2l0eWludHJhKGZuZXRbLCAsIDJdLCBldGhtaW56bSkNCmRlc21hdFs2LCAzXSA8LSBmZGVuc2l0eWludHJhKGZuZXRbLCAsIDNdLCBldGhtaW56bSkNCmRlc21hdFs3LCAxXSA8LSBmZGVuc2l0eWludGVyKGZuZXRbLCAsIDFdLCBldGhtaW56bSkNCmRlc21hdFs3LCAyXSA8LSBmZGVuc2l0eWludGVyKGZuZXRbLCAsIDJdLCBldGhtaW56bSkNCmRlc21hdFs3LCAzXSA8LSBmZGVuc2l0eWludGVyKGZuZXRbLCAsIDNdLCBldGhtaW56bSkNCmRlc21hdFs4LCAxXSA8LSBmZGVuc2l0eWludGVyKGZuZXRbLCAsIDFdLCBtaW5vcml0eW0pDQpkZXNtYXRbOCwgMl0gPC0gZmRlbnNpdHlpbnRlcihmbmV0WywgLCAyXSwgbWlub3JpdHltKQ0KZGVzbWF0WzgsIDNdIDwtIGZkZW5zaXR5aW50ZXIoZm5ldFssICwgM10sIG1pbm9yaXR5bSkNCmRlc21hdFs5LCAxXSA8LSBmZGVuc2l0eWludHJhKGZuZXRbLCAsIDFdLCBsZnRtKQ0KZGVzbWF0WzksIDJdIDwtIGZkZW5zaXR5aW50cmEoZm5ldFssICwgMl0sIGxmdG0pDQpkZXNtYXRbOSwgM10gPC0gZmRlbnNpdHlpbnRyYShmbmV0WywgLCAzXSwgbGZ0bSkNCmRlc21hdFsxMCwgMV0gPC0gZmRlbnNpdHlpbnRlcihmbmV0WywgLCAxXSwgbGZ0bSkNCmRlc21hdFsxMCwgMl0gPC0gZmRlbnNpdHlpbnRlcihmbmV0WywgLCAyXSwgbGZ0bSkNCmRlc21hdFsxMCwgM10gPC0gZmRlbnNpdHlpbnRlcihmbmV0WywgLCAzXSwgbGZ0bSkNCg0KZGVzbWF0WzEsIDEgKyAzXSA8LSBmZGVuc2l0eShhdG1uZXRbLCAsIDFdKQ0KZGVzbWF0WzEsIDIgKyAzXSA8LSBmZGVuc2l0eShhdG1uZXRbLCAsIDJdKQ0KZGVzbWF0WzEsIDMgKyAzXSA8LSBmZGVuc2l0eShhdG1uZXRbLCAsIDNdKQ0KZGVzbWF0WzIsIDEgKyAzXSA8LSBmZGVuc2l0eWludHJhKGF0bW5ldFssICwgMV0sIHZyb3V3bSkNCmRlc21hdFsyLCAyICsgM10gPC0gZmRlbnNpdHlpbnRyYShhdG1uZXRbLCAsIDJdLCB2cm91d20pDQpkZXNtYXRbMiwgMyArIDNdIDwtIGZkZW5zaXR5aW50cmEoYXRtbmV0WywgLCAzXSwgdnJvdXdtKQ0KZGVzbWF0WzMsIDEgKyAzXSA8LSBmZGVuc2l0eWludGVyKGF0bW5ldFssICwgMV0sIHZyb3V3bSkNCmRlc21hdFszLCAyICsgM10gPC0gZmRlbnNpdHlpbnRlcihhdG1uZXRbLCAsIDJdLCB2cm91d20pDQpkZXNtYXRbMywgMyArIDNdIDwtIGZkZW5zaXR5aW50ZXIoYXRtbmV0WywgLCAzXSwgdnJvdXdtKQ0KZGVzbWF0WzQsIDEgKyAzXSA8LSBmZGVuc2l0eWludHJhKGF0bW5ldFssICwgMV0sIHBhcnRpam0pDQpkZXNtYXRbNCwgMiArIDNdIDwtIGZkZW5zaXR5aW50cmEoYXRtbmV0WywgLCAyXSwgcGFydGlqbSkNCmRlc21hdFs0LCAzICsgM10gPC0gZmRlbnNpdHlpbnRyYShhdG1uZXRbLCAsIDNdLCBwYXJ0aWptKQ0KZGVzbWF0WzUsIDEgKyAzXSA8LSBmZGVuc2l0eWludGVyKGF0bW5ldFssICwgMV0sIHBhcnRpam0pDQpkZXNtYXRbNSwgMiArIDNdIDwtIGZkZW5zaXR5aW50ZXIoYXRtbmV0WywgLCAyXSwgcGFydGlqbSkNCmRlc21hdFs1LCAzICsgM10gPC0gZmRlbnNpdHlpbnRlcihhdG1uZXRbLCAsIDNdLCBwYXJ0aWptKQ0KZGVzbWF0WzYsIDEgKyAzXSA8LSBmZGVuc2l0eWludHJhKGF0bW5ldFssICwgMV0sIGV0aG1pbnptKQ0KZGVzbWF0WzYsIDIgKyAzXSA8LSBmZGVuc2l0eWludHJhKGF0bW5ldFssICwgMl0sIGV0aG1pbnptKQ0KZGVzbWF0WzYsIDMgKyAzXSA8LSBmZGVuc2l0eWludHJhKGF0bW5ldFssICwgM10sIGV0aG1pbnptKQ0KZGVzbWF0WzcsIDEgKyAzXSA8LSBmZGVuc2l0eWludGVyKGF0bW5ldFssICwgMV0sIGV0aG1pbnptKQ0KZGVzbWF0WzcsIDIgKyAzXSA8LSBmZGVuc2l0eWludGVyKGF0bW5ldFssICwgMl0sIGV0aG1pbnptKQ0KZGVzbWF0WzcsIDMgKyAzXSA8LSBmZGVuc2l0eWludGVyKGF0bW5ldFssICwgM10sIGV0aG1pbnptKQ0KZGVzbWF0WzgsIDEgKyAzXSA8LSBmZGVuc2l0eWludGVyKGF0bW5ldFssICwgMV0sIG1pbm9yaXR5bSkNCmRlc21hdFs4LCAyICsgM10gPC0gZmRlbnNpdHlpbnRlcihhdG1uZXRbLCAsIDJdLCBtaW5vcml0eW0pDQpkZXNtYXRbOCwgMyArIDNdIDwtIGZkZW5zaXR5aW50ZXIoYXRtbmV0WywgLCAzXSwgbWlub3JpdHltKQ0KZGVzbWF0WzksIDEgKyAzXSA8LSBmZGVuc2l0eWludHJhKGF0bW5ldFssICwgMV0sIGxmdG0pDQpkZXNtYXRbOSwgMiArIDNdIDwtIGZkZW5zaXR5aW50cmEoYXRtbmV0WywgLCAyXSwgbGZ0bSkNCmRlc21hdFs5LCAzICsgM10gPC0gZmRlbnNpdHlpbnRyYShhdG1uZXRbLCAsIDNdLCBsZnRtKQ0KZGVzbWF0WzEwLCAxICsgM10gPC0gZmRlbnNpdHlpbnRlcihhdG1uZXRbLCAsIDFdLCBsZnRtKQ0KZGVzbWF0WzEwLCAyICsgM10gPC0gZmRlbnNpdHlpbnRlcihhdG1uZXRbLCAsIDJdLCBsZnRtKQ0KZGVzbWF0WzEwLCAzICsgM10gPC0gZmRlbnNpdHlpbnRlcihhdG1uZXRbLCAsIDNdLCBsZnRtKQ0KDQpkZXNtYXRbMSwgMSArIDZdIDwtIGZkZW5zaXR5KHJ0bmV0WywgLCAxXSkNCmRlc21hdFsxLCAyICsgNl0gPC0gZmRlbnNpdHkocnRuZXRbLCAsIDJdKQ0KZGVzbWF0WzEsIDMgKyA2XSA8LSBmZGVuc2l0eShydG5ldFssICwgM10pDQpkZXNtYXRbMiwgMSArIDZdIDwtIGZkZW5zaXR5aW50cmEocnRuZXRbLCAsIDFdLCB2cm91d20pDQpkZXNtYXRbMiwgMiArIDZdIDwtIGZkZW5zaXR5aW50cmEocnRuZXRbLCAsIDJdLCB2cm91d20pDQpkZXNtYXRbMiwgMyArIDZdIDwtIGZkZW5zaXR5aW50cmEocnRuZXRbLCAsIDNdLCB2cm91d20pDQpkZXNtYXRbMywgMSArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDFdLCB2cm91d20pDQpkZXNtYXRbMywgMiArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDJdLCB2cm91d20pDQpkZXNtYXRbMywgMyArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDNdLCB2cm91d20pDQpkZXNtYXRbNCwgMSArIDZdIDwtIGZkZW5zaXR5aW50cmEocnRuZXRbLCAsIDFdLCBwYXJ0aWptKQ0KZGVzbWF0WzQsIDIgKyA2XSA8LSBmZGVuc2l0eWludHJhKHJ0bmV0WywgLCAyXSwgcGFydGlqbSkNCmRlc21hdFs0LCAzICsgNl0gPC0gZmRlbnNpdHlpbnRyYShydG5ldFssICwgM10sIHBhcnRpam0pDQpkZXNtYXRbNSwgMSArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDFdLCBwYXJ0aWptKQ0KZGVzbWF0WzUsIDIgKyA2XSA8LSBmZGVuc2l0eWludGVyKHJ0bmV0WywgLCAyXSwgcGFydGlqbSkNCmRlc21hdFs1LCAzICsgNl0gPC0gZmRlbnNpdHlpbnRlcihydG5ldFssICwgM10sIHBhcnRpam0pDQpkZXNtYXRbNiwgMSArIDZdIDwtIGZkZW5zaXR5aW50cmEocnRuZXRbLCAsIDFdLCBldGhtaW56bSkNCmRlc21hdFs2LCAyICsgNl0gPC0gZmRlbnNpdHlpbnRyYShydG5ldFssICwgMl0sIGV0aG1pbnptKQ0KZGVzbWF0WzYsIDMgKyA2XSA8LSBmZGVuc2l0eWludHJhKHJ0bmV0WywgLCAzXSwgZXRobWluem0pDQpkZXNtYXRbNywgMSArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDFdLCBldGhtaW56bSkNCmRlc21hdFs3LCAyICsgNl0gPC0gZmRlbnNpdHlpbnRlcihydG5ldFssICwgMl0sIGV0aG1pbnptKQ0KZGVzbWF0WzcsIDMgKyA2XSA8LSBmZGVuc2l0eWludGVyKHJ0bmV0WywgLCAzXSwgZXRobWluem0pDQpkZXNtYXRbOCwgMSArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDFdLCBtaW5vcml0eW0pDQpkZXNtYXRbOCwgMiArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDJdLCBtaW5vcml0eW0pDQpkZXNtYXRbOCwgMyArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDNdLCBtaW5vcml0eW0pDQpkZXNtYXRbOSwgMSArIDZdIDwtIGZkZW5zaXR5aW50cmEocnRuZXRbLCAsIDFdLCBsZnRtKQ0KZGVzbWF0WzksIDIgKyA2XSA8LSBmZGVuc2l0eWludHJhKHJ0bmV0WywgLCAyXSwgbGZ0bSkNCmRlc21hdFs5LCAzICsgNl0gPC0gZmRlbnNpdHlpbnRyYShydG5ldFssICwgM10sIGxmdG0pDQpkZXNtYXRbMTAsIDEgKyA2XSA8LSBmZGVuc2l0eWludGVyKHJ0bmV0WywgLCAxXSwgbGZ0bSkNCmRlc21hdFsxMCwgMiArIDZdIDwtIGZkZW5zaXR5aW50ZXIocnRuZXRbLCAsIDJdLCBsZnRtKQ0KZGVzbWF0WzEwLCAzICsgNl0gPC0gZmRlbnNpdHlpbnRlcihydG5ldFssICwgM10sIGxmdG0pDQoNCmNvbG5hbWVzKGRlc21hdCkgPC0gYygiZnJpZW5kcyB3MSIsICJmcmllbmRzIHcyIiwgImZyaWVuZHMgdzMiLCAiYXRtZW50aW9ucyB3MSIsICJhdG1lbnRpb25zIHcyIiwgImF0bWVudGlvbnMgdzMiLCANCiAgICAicmV0d2VldHMgdzEiLCAicmV0d2VldHMgdzIiLCAicmV0d2VldHMgdzMiKQ0Kcm93bmFtZXMoZGVzbWF0KSA8LSBjKCJ0b3RhbCIsICJzYW1lIHNleCIsICJkaWZmZXJlbnQgc2V4IiwgInNhbWUgcGFydHkiLCAiZGlmZmVyZW50IHBhcnR5IiwgInNhbWUgZXRobmljaXR5IiwgDQogICAgImRpZmZlcmVudCBldGhuaWNpdHkiLCAiYm90aCBtaW5vcml0eSIsICJzYW1lIGFnZSAoPDYpIiwgImRpZmZlcmVudCBhZ2UgKD41KSIpDQpkZXNtYXQNCg0KDQoNCiMgd2Ugb2JzZXJ2ZSBhIGxvdCBvZiBob21vcGhpbHkuIE1haW5seSBiaWcgZGlmZmVyZW5jZSBpbiBkZW5zaXR5IGJldHdlZW4gYW5kIHdoaXRoaW4gcG9saXRpY2FsIHBhcnRpZXMuIEhvbW9waGlseSBpcyBub3QgdGhhdCBzdHJvbmcgYWNyb3NzIHNvY2lhbCBkaW1lbnNpb25zLg0KYGBgDQoNCg0KY29sZW1hbiBob21vcGhpbHkNCmBgYHtyfQ0KIyBCZWNhdXNlIHNpemUgb2YgZGlmZmVyZW50IHN1Ymdyb3VwcyB2YXJ5IGFuZCBudW1iZXIgb2Ygb3V0LWRlZ3JlZXMgZGlmZmVycyBiZXR3ZWVuIE1Qcywgd2hpdGluIHBhcnR5IGRlbnNpdGllcyBtaWdodCBiZSBoaWdoZXIgd2hlbiBNUHMgcmFuZG9tbHkgc2VsZWN0IHBhcnRuZXIvYWx0ZXIuIFNlZ3JlZ2F0aW9uIHdpbGwgcGFydGx5IGJlIHN0cnVjdHVsbHkgaW5kdWNlZCBieSBkaWZmZXJlbmNlcyBpbiByZWxhdGl2ZSBncm91cHMgc2l6ZXMgYW5kIGFjdGl2aXR5IG9uIHR3aXR0ZXIuIENvbGVtYW4ncyBob21vcGhpbHkgaW5kZXg6IHRha2VzIHJlbGF0aXZlIGdyb3VwIHNpemVzIGFuZCBkaWZmZXJlbmNlcyBpbnRvIGFjY291bnQuIDAgLT4gb2JzZXJ2ZWQgbnVtYmVyIG9mIHdpdGhpbi1ncm91cCB0aWVzIGlzIHRoZSBzYW1lIGFzIHdvdWxkIGJlIGV4cGVjdGVkIHVuZGVyIHJhbmRvbSBjaG9pY2UuIDEgLT4gbWF4aW11bSBzZWdyZWdhdGlvbi4gLTEgLT4gTVBzIG1heGltYWxseSBhdm9pZCB3aXRoaW4gZ3JvdXAgcmVsYXRpb25zLg0KDQoNCmNvbG1hdCA8LSBtYXRyaXgoTkEsIG5yb3cgPSAzLCBuY29sID0gOSkNCg0KY29sbWF0WzEsIDFdIDwtIGZzY29sbmV0KGZuZXRbLCAsIDFdLCBwYXJ0aWopDQpjb2xtYXRbMSwgMl0gPC0gZnNjb2xuZXQoZm5ldFssICwgMl0sIHBhcnRpaikNCmNvbG1hdFsxLCAzXSA8LSBmc2NvbG5ldChmbmV0WywgLCAzXSwgcGFydGlqKQ0KY29sbWF0WzEsIDRdIDwtIGZzY29sbmV0KGF0bW5ldFssICwgMV0sIHBhcnRpaikNCmNvbG1hdFsxLCA1XSA8LSBmc2NvbG5ldChhdG1uZXRbLCAsIDJdLCBwYXJ0aWopDQpjb2xtYXRbMSwgNl0gPC0gZnNjb2xuZXQoYXRtbmV0WywgLCAzXSwgcGFydGlqKQ0KY29sbWF0WzEsIDddIDwtIGZzY29sbmV0KHJ0bmV0WywgLCAxXSwgcGFydGlqKQ0KY29sbWF0WzEsIDhdIDwtIGZzY29sbmV0KHJ0bmV0WywgLCAyXSwgcGFydGlqKQ0KY29sbWF0WzEsIDldIDwtIGZzY29sbmV0KHJ0bmV0WywgLCAzXSwgcGFydGlqKQ0KDQpjb2xtYXRbMiwgMV0gPC0gZnNjb2xuZXQoZm5ldFssICwgMV0sIHZyb3V3KQ0KY29sbWF0WzIsIDJdIDwtIGZzY29sbmV0KGZuZXRbLCAsIDJdLCB2cm91dykNCmNvbG1hdFsyLCAzXSA8LSBmc2NvbG5ldChmbmV0WywgLCAzXSwgdnJvdXcpDQpjb2xtYXRbMiwgNF0gPC0gZnNjb2xuZXQoYXRtbmV0WywgLCAxXSwgdnJvdXcpDQpjb2xtYXRbMiwgNV0gPC0gZnNjb2xuZXQoYXRtbmV0WywgLCAyXSwgdnJvdXcpDQpjb2xtYXRbMiwgNl0gPC0gZnNjb2xuZXQoYXRtbmV0WywgLCAzXSwgdnJvdXcpDQpjb2xtYXRbMiwgN10gPC0gZnNjb2xuZXQocnRuZXRbLCAsIDFdLCB2cm91dykNCmNvbG1hdFsyLCA4XSA8LSBmc2NvbG5ldChydG5ldFssICwgMl0sIHZyb3V3KQ0KY29sbWF0WzIsIDldIDwtIGZzY29sbmV0KHJ0bmV0WywgLCAzXSwgdnJvdXcpDQoNCmNvbG1hdFszLCAxXSA8LSBmc2NvbG5ldChmbmV0WywgLCAxXSwgZXRobWlueikNCmNvbG1hdFszLCAyXSA8LSBmc2NvbG5ldChmbmV0WywgLCAyXSwgZXRobWlueikNCmNvbG1hdFszLCAzXSA8LSBmc2NvbG5ldChmbmV0WywgLCAzXSwgZXRobWlueikNCmNvbG1hdFszLCA0XSA8LSBmc2NvbG5ldChhdG1uZXRbLCAsIDFdLCBldGhtaW56KQ0KY29sbWF0WzMsIDVdIDwtIGZzY29sbmV0KGF0bW5ldFssICwgMl0sIGV0aG1pbnopDQpjb2xtYXRbMywgNl0gPC0gZnNjb2xuZXQoYXRtbmV0WywgLCAzXSwgZXRobWlueikNCmNvbG1hdFszLCA3XSA8LSBmc2NvbG5ldChydG5ldFssICwgMV0sIGV0aG1pbnopDQpjb2xtYXRbMywgOF0gPC0gZnNjb2xuZXQocnRuZXRbLCAsIDJdLCBldGhtaW56KQ0KY29sbWF0WzMsIDldIDwtIGZzY29sbmV0KHJ0bmV0WywgLCAzXSwgZXRobWlueikNCg0KY29sbmFtZXMoY29sbWF0KSA8LSBjKCJmcmllbmRzIHcxIiwgImZyaWVuZHMgdzIiLCAiZnJpZW5kcyB3MyIsICJhdG1lbnRpb25zIHcxIiwgImF0bWVudGlvbnMgdzIiLCAiYXRtZW50aW9ucyB3MyIsIA0KICAgICJyZXR3ZWV0cyB3MSIsICJyZXR3ZWV0cyB3MiIsICJyZXR3ZWV0cyB3MyIpDQpyb3duYW1lcyhjb2xtYXQpIDwtIGMoInBhcnR5IiwgInNleCIsICJldGhuaWNpdHkiKQ0KY29sbWF0DQpgYGANCg0KDQpSU2llbm5hDQpgYGB7cn0NCiMgZGVmaW5pbmcgbXllZmYgb2JqZWN0DQpsaWJyYXJ5KFJTaWVuYSkNCm15ZWZmIDwtIGdldEVmZmVjdHMobXlkYXRhKQ0KbXllZmYNCg0KbXllZmZfbTEgPC0gbXllZmYNCm15ZWZmX20xIDwtIGluY2x1ZGVFZmZlY3RzKG15ZWZmX20xLCBzYW1lWCwgaW50ZXJhY3Rpb24xID0gInBhcnRpaiIsIG5hbWUgPSAicnRuZXQiKQ0KDQoNCg0KIyBJIHVzZWQgYSBzZWVkIHNvIHlvdSB3aWxsIHByb2JhYmx5IHNlZSB0aGUgc2FtZSByZXN1bHRzDQpteWFsZ29yaXRobSA8LSBzaWVuYUFsZ29yaXRobUNyZWF0ZShwcm9qbmFtZSA9ICJ0ZXN0Iiwgc2VlZCA9IDM0NTY1NCkNCg0KDQoNCiMgdG8gc3BlZWQgdGhpbmdzIHVwIGEgYml0LCBJIGFtIHVzaW5nIG1vcmUgY29yZXMuDQphbnNNMSA8LSBzaWVuYTA3KG15YWxnb3JpdGhtLCBkYXRhID0gbXlkYXRhLCBlZmZlY3RzID0gbXllZmZfbTEsIHVzZUNsdXN0ZXIgPSBUUlVFLCBuYnJOb2RlcyA9IDQsIGluaXRDID0gVFJVRSwgDQogICAgYmF0Y2ggPSBUUlVFKQ0KYW5zTTFiIDwtIHNpZW5hMDcobXlhbGdvcml0aG0sIGRhdGEgPSBteWRhdGEsIHByZXZBbnMgPSBhbnNNMSwgZWZmZWN0cyA9IG15ZWZmX20xLCB1c2VDbHVzdGVyID0gVFJVRSwgDQogICAgbmJyTm9kZXMgPSA0LCBpbml0QyA9IFRSVUUsIGJhdGNoID0gVFJVRSkNCmFuc00xYyA8LSBzaWVuYTA3KG15YWxnb3JpdGhtLCBkYXRhID0gbXlkYXRhLCBwcmV2QW5zID0gYW5zTTFiLCBlZmZlY3RzID0gbXllZmZfbTEsIHVzZUNsdXN0ZXIgPSBUUlVFLCANCiAgICBuYnJOb2RlcyA9IDQsIGluaXRDID0gVFJVRSwgYmF0Y2ggPSBUUlVFKQ0KDQpzYXZlKGFuc00xLCBmaWxlID0gImFuc00xYS5SRGF0YSIpDQpzYXZlKGFuc00xYiwgZmlsZSA9ICJhbnNNMWIuUkRhdGEiKQ0Kc2F2ZShhbnNNMWMsIGZpbGUgPSAiYW5zTTFjLlJEYXRhIikNCg0KDQoNCmxvYWQoImFuc00xYS5SRGF0YSIpDQpsb2FkKCJhbnNNMWIuUkRhdGEiKQ0KbG9hZCgiYW5zTTFjLlJEYXRhIikNCmFuc00xDQoNCmFuc00xYg0KDQphbnNNMWMNCg0KDQojVG8gd2hhdCBleHRlbnQgZG8gd2Ugb2JzZXJ2ZSBzZWdyZWdhdGlvbiBhbG9uZyBwYXJ0eSBhZmZpbGlhdGlvbiBpbiB0aGUgcmV0d2VldCBuZXR3b3JrIGFtb25nIER1dGNoIE1Qcz8NCg0KIyBBbnN3ZXI6IHRoZSBldmFsIHNhbWUgcGFydGlqIGlzIDEuODU1MS4gVGhpcyBtZWFucyB0aGF0IHdlIG9ic2VydmUgc3Ryb25nIHNlZ3JlZ2F0aW9uIGFsb25nIHBhcnkgYWZmaWxpYXRpb246IHBlb3BsZSBhcmUgbW9yZSBsaWtlbHkgdG8gaGF2ZSB0aWVzIHdpdGggcGVvcGxlIGZyb20gdGhlIHNhbWUgcGFydHkNCg0KYGBgDQoNCg0KUlEgMQ0KYGBge3J9DQpteWVmZl9tMiA8LSBteWVmZg0KbXllZmZfbTIgPC0gaW5jbHVkZUVmZmVjdHMobXllZmZfbTIsIHNhbWVYLCBpbnRlcmFjdGlvbjEgPSAicGFydGlqIiwgbmFtZSA9ICJydG5ldCIpDQoNCg0KbXllZmZfbTIgPC0gbXllZmYNCm15ZWZmX20yIDwtIGluY2x1ZGVFZmZlY3RzKG15ZWZmX20yLCBzYW1lWCwgaW50ZXJhY3Rpb24xID0gInZyb3V3IiwgbmFtZSA9ICJydG5ldCIpDQoNCg0KbXllZmZfbTIgPC0gbXllZmYNCm15ZWZmX20yIDwtIGluY2x1ZGVFZmZlY3RzKG15ZWZmX20yLCBzYW1lWCwgaW50ZXJhY3Rpb24xID0gImxmdCIsIG5hbWUgPSAicnRuZXQiKQ0KDQpteWVmZl9tMiA8LSBteWVmZg0KbXllZmZfbTIgPC0gaW5jbHVkZUVmZmVjdHMobXllZmZfbTIsIFgsIGludGVyYWN0aW9uMSA9ICJhZnN0YW5kIiwgbmFtZSA9ICJydG5ldCIpDQpgYGANCg0KDQoNCmBgYHtyfQ0KDQpgYGANCg0K